package com.gthncz.xxhelper.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Build;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.support.constraint.ConstraintLayout;
import android.support.v7.widget.AppCompatImageButton;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

import com.gthncz.xxhelper.R;
import com.gthncz.xxhelper.adapters.SubjectListAdapter;
import com.gthncz.xxhelper.commons.Utils;
import com.gthncz.xxhelper.greendao.Subject;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by GT on 2019/11/10.
 */

public class MainService extends Service {

    private static final String TAG = MainService.class.getSimpleName();

    private WindowManager windowManager;
    // 搜索按钮界面
    private ConstraintLayout toucherLayout;
    private WindowManager.LayoutParams params;
    // 搜索列表界面
    private LinearLayout searchLayout;
    private WindowManager.LayoutParams searchLayoutParams;

    // 状态栏高度
    private int statusBarHeight = -1;
    // 屏幕宽高
    private int windowWidth = -1;
    private int windowHeight = -1;
    // 数据访问服务
    private DAOService daoService;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null; // 不与 Activity 绑定
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "MainService created.");
        daoService = new DAOService(MainService.this);

        windowManager = (WindowManager) getApplication().getSystemService(Context.WINDOW_SERVICE);
        int[] size = Utils.getWindowWidthAndHeight(this);
        windowWidth = size[0];
        windowHeight = size[1];
        // 生成悬浮窗
        createToucher();
    }

    /**********************************************
     * 悬浮搜索按钮界面
     **********************************************/

    private void createToucher() {
        if (toucherLayout != null){
            // 直接添加 toucherLayout
            windowManager.addView(toucherLayout, params);
            return;
        }  // 否则，需要初始化参数，才能添加到 windowManager
        // 赋值 LayoutParams
        params = new WindowManager.LayoutParams();
        // 设置 type. 系统提示窗口, 一般都在应用程序窗口之上
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        }
        // 设置效果为背景透明
        params.format = PixelFormat.RGBA_8888;
        // 设置 flags, 不可聚焦及不可使用按钮对悬浮窗进行操作
        params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
        // 设置窗口初始停靠位置
        params.gravity = Gravity.LEFT | Gravity.TOP;
        params.x = windowWidth; // !important 这里的 x 和 gravity 是配合起来用的，如果使用 Gravity.RIGTH, 那么设置的 x 将和实际效果相反。
        params.y = windowHeight/2;
        // 设置悬浮窗长宽
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        LayoutInflater layoutInflater = LayoutInflater.from(MainService.this);
        toucherLayout = (ConstraintLayout) layoutInflater.inflate(R.layout.layout_float, null);
        // 添加 toucherLayout
        windowManager.addView(toucherLayout, params);
        // 主动计算出当前 View 的宽高信息
        toucherLayout.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

        // 用于检测状态栏高度
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if(resourceId > 0){
            statusBarHeight = getResources().getDimensionPixelSize(resourceId);
        }
        Log.i(TAG, "状态栏高度为: " + statusBarHeight);

        // 浮动窗口按钮
        AppCompatImageButton imageButton = (AppCompatImageButton)toucherLayout.findViewById(R.id.imageButton_search);

        // 设置悬浮按钮点击事件
        imageButton.setOnClickListener(new SearchListener());
        imageButton.setOnLongClickListener(new SearchListener());
        // 设置悬浮按钮拖动事件
        imageButton.setOnTouchListener(new SearchTouchListener());
    }

    private class SearchListener implements View.OnClickListener, View.OnLongClickListener {
        long[] hints = new long[3]; // 当前点击时间, 上一次点击时间, 上次双击时间
        @Override
        public void onClick(View v) {
            Log.i(TAG, "ImageButton on clicked.");
            // Toast.makeText(MainService.this, "ImageButton on clicked.", Toast.LENGTH_SHORT).show();
            System.arraycopy(hints, 1, hints, 0, 1);  // 上一次的点击时间
            hints[1] = SystemClock.uptimeMillis();  // 本次的点击时间
            if (SystemClock.uptimeMillis() - hints[0] >= 700){  // 如果两次点击时间间隔大于 700，则是单击
                windowManager.removeView(toucherLayout);
                createSearcher();
            } else { // 本次是双击
                if (SystemClock.uptimeMillis() - hints[2] >= 1000){
                    hints[2] = SystemClock.uptimeMillis(); // 本次双击的时间
                    Toast.makeText(MainService.this, "再次双击退出~", Toast.LENGTH_SHORT).show();
                } else {
                    Log.e(TAG, "即将关闭");
                    stopSelf();
                }
            }
        }

        @Override
        public boolean onLongClick(View v) {
            Log.e(TAG, "即将关闭");
            Toast.makeText(MainService.this, "即将关闭~", Toast.LENGTH_SHORT).show();
            stopSelf();
            return true;
        }
    }

    private class SearchTouchListener implements View.OnTouchListener {
        boolean isFirstUp = false;
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // 判断是否 ACTION
            switch (event.getAction()){
                case MotionEvent.ACTION_MOVE:{
                    // 判断移动距离
                    float translationX = event.getX() - v.getWidth()/2;
                    float translationY = event.getY() - v.getHeight()/2;
                    double distance = Math.sqrt(Math.pow(translationX, 2) + Math.pow(translationY, 2));
                    // Log.e(TAG, "move distance:" + distance);
                    if (distance > 50.0){
                        params.x = (int)(event.getRawX() - v.getWidth()/2);
                        params.y = (int)(event.getRawY() - v.getHeight()/2 - statusBarHeight);
                        Log.e(TAG, "param x:" + params.x + " y: " + params.y);
                        windowManager.updateViewLayout(toucherLayout, params);
                        isFirstUp = true; // 拦截第一次抬起事件
                        // TODO 悬浮按钮自动靠边
                        return true; // 拦截移动事件
                    }
                }
                case MotionEvent.ACTION_UP:{
                    if (isFirstUp){
                        isFirstUp = false;
                        return true;
                    }
                    break;
                }
            }
            return false;
        }
    }

    /**********************************************
     * 搜索列表界面
     **********************************************/

    // 需要使用的控件、数据等
    private EditText editText;
    private SubjectListAdapter adapter;
    private List<Subject> resultList;

    // 搜索页面
    private void createSearcher(){
        if (searchLayout != null){
            if(editText != null) editText.setText("");
            if(resultList != null) resultList.clear();
            windowManager.addView(searchLayout, searchLayoutParams);
            return;
        }

        searchLayoutParams = new WindowManager.LayoutParams();
        // 设置 type. 系统提示窗口, 一般都在应用程序窗口之上
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            searchLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            searchLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        }
        // 设置效果为背景透明
        searchLayoutParams.format = PixelFormat.RGBA_8888;
        // 设置 flags, 允许聚焦 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, 外部调暗
        searchLayoutParams.flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                | WindowManager.LayoutParams.FLAG_DIM_BEHIND;
        searchLayoutParams.dimAmount = 0.2f; // 背景亮暗
        searchLayoutParams.alpha = 1.0f;  // 悬浮窗透明度
        // 设置窗口初始停靠位置
        searchLayoutParams.gravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP;
        searchLayoutParams.x = 0;
        searchLayoutParams.y = 0;
        // 设置悬浮窗长宽
        searchLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
        searchLayoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
        LayoutInflater layoutInflater = LayoutInflater.from(MainService.this);
        searchLayout = (LinearLayout) layoutInflater.inflate(R.layout.layout_search, null);
        windowManager.addView(searchLayout, searchLayoutParams);
        // 页面上的事件处理
        handleSearchPage();
    }

    private void handleSearchPage(){
        // 页面上的事件处理
        final LinearLayout contentLayout = searchLayout.findViewById(R.id.linearLayout_search);
        LinearLayout.LayoutParams contentLayoutParams = (LinearLayout.LayoutParams) contentLayout.getLayoutParams();
        contentLayoutParams.height = (int)(0.8*windowHeight);
        searchLayout.updateViewLayout(contentLayout, contentLayoutParams);

        searchLayout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                float x = event.getX();
                float y = event.getY();
                Rect rect = new Rect();
                contentLayout.getGlobalVisibleRect(rect);
                if (!rect.contains((int)x, (int)y)){
                    Log.e(TAG, "点击了外部!");
                    windowManager.removeView(searchLayout);
                    createToucher();
                    return true;
                }
                return false;
            }
        });
        // TODO 解决按 Back 键返回没有作用
        searchLayout.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                Log.e(TAG, "Key event: " + event.getCharacters());
                switch (keyCode){
                    // 点击了返回键, 悬浮窗消失
                    case KeyEvent.KEYCODE_BACK:{
                        Log.e(TAG, "点击了返回键!");
                        windowManager.removeView(searchLayout);
                        createToucher();
                        return true;
                    }
                }
                return false;
            }
        });
        // 设置 适配器
        resultList = new ArrayList<>();
        adapter = new SubjectListAdapter(MainService.this, resultList);
        ListView listView = searchLayout.findViewById(R.id.recyleView_search);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.e(TAG, "item " + position + " clicked.");
            }
        });

        // 设置 EditText 的监听
        editText = searchLayout.findViewById(R.id.editText_search);
        editText.addTextChangedListener(new SearchEditorWacth());
        // 设置 SearchButton 的监听
        ImageButton imageButton = searchLayout.findViewById(R.id.imageButton_justgo);
        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String content = editText.getText().toString();
                searchResult(content);
            }
        });
    }

    private class SearchEditorWacth implements TextWatcher {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {}
        @Override
        public void afterTextChanged(Editable s) {
            String content = s.toString();
            searchResult(content);
        }
    }

    private void searchResult(String content) {
        if (content.trim().equals("")) return;
        String[] keywords = content.split(" +");
        if (keywords.length == 0) return;
        resultList = daoService.findSubjectByKeywords(keywords);
        Log.e(TAG, "-------------search result---------------");
        for(Subject subject: resultList){
            Log.i(TAG, subject.toString());
        }
        Log.e(TAG, "-----------------------------------------");
        adapter.setData(resultList);
        // adapter.notifyDataSetChanged();  // 会保留滑动的位置信息
        adapter.notifyDataSetInvalidated(); // 会清空状态信息
    }

    @Override
    public void onDestroy() {
        if (toucherLayout != null){
            windowManager.removeView(toucherLayout);
        }
        if (searchLayout != null){
            windowManager.removeView(searchLayout);
        }
        super.onDestroy();
    }
}
